using System.Activities.Statements;
using System.Collections.Generic;
using Headsight.BPMN2WF.BPMN.Model;
using Headsight.BPMN2WF.BPMN.Utils;

namespace Headsight.BPMN2WF.Transformation.Transformers
{
    /// <summary>
    /// 
    /// </summary>
    public class BPMN2WFTransformationFlowchart : IBPMN2WFTransformation
    {
        private Flowchart _flowchart;
        private FlowStep _flowOut;

        public BPMNTransformationResult Transform(IBPMN2WFTransformationContext ctx, BPMNFlowNode flowNode)
        {
            var block = (BPMNFlowNodesBlock)flowNode;

            _flowchart = new Flowchart();

            var transformation = ctx.BPMN2WFTransformations.Get(block.FlowNodeIn);

            _flowchart.StartNode = transformation.Transform(ctx, block.FlowNodeIn).Result.ToFlowStep();
            _flowchart.Nodes.Add(_flowchart.StartNode);

            _flowOut = (FlowStep) ((block.NodeOut != null) ? _flowchart.StartNode : null);

            TransformRecursive(ctx, block, block.GetNextNodesInFlowFrom(block.FlowNodeIn), _flowchart.StartNode);

            return new BPMNTransformationResult(_flowchart, _flowchart.StartNode, _flowOut);
        }

        private void TransformRecursive(IBPMN2WFTransformationContext ctx, BPMNFlowNodesBlock processBlock, IEnumerable<BPMNFlowNode> bpmnFlowNodes, FlowNode previousFlowStep)
        {
            // Should be always just one single node within bpmnFlowNodes, but...
            foreach (var each in bpmnFlowNodes)
            {
                var eachResult = ctx.BPMN2WFTransformations.Get(each).Transform(ctx, each);
                var eachFlowStep = eachResult.Result.ToFlowStep();

                _flowchart.Nodes.Add(eachFlowStep);
                ((FlowStep)previousFlowStep).Next = eachFlowStep;

                if (each.Equals(processBlock.NodeOut))
                {
                    _flowOut = eachFlowStep;
                }

                TransformRecursive(ctx, processBlock, processBlock.GetNextNodesInFlowFrom(each), eachFlowStep);
            }
        }
    }
}